from fastapi import APIRouter, Request, HTTPException, Depends, status
from tortoise.expressions import Q

from . import scheams, models
from ... import settings
from ...utils import wechat_tools, tools
from ...utils.jwt_tool import JwtToken

app = APIRouter()


@app.post("/wx/register", response_model=scheams.UserRegisterResponse)
async def register_user(request: Request, user_info: scheams.UserRegisterRequest):
    """处理用户注册请求逻辑"""
    # 1.验证用户信息
    print(user_info)
    user = await models.User.filter(mobile=user_info.mobile).first()
    print(user)
    if user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="手机号已注册")
    # 2.判断验证码是否正确
    redis = request.app.state.redis
    sms_code = await redis.get(f"sms:{user_info.mobile}")
    if sms_code is None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="验证码已过期")
    if sms_code != user_info.sms_code:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="验证码错误")
    # 3.获取openid
    wechat_user = wechat_tools.get_wechat_info(user_info.code)
    print("wechat_user", wechat_user)
    if not wechat_user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="获取微信信息失败")
    # 4.判断微信是否已绑定其他账号
    user = await models.User.filter(openid=wechat_user['openid']).first()
    if user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="微信已绑定其他账号")
    # 5.创建用户
    user = await models.User.create(
        **dict(user_info),
        username=user_info.mobile,
        avatar=user_info.avatarUrl,
        nickname=user_info.nickName,
        sex=user_info.gender,
        openid=wechat_user['openid'],
    )
    # 6.生成token并保存到redis中
    token = JwtToken.create_token({
        'id': user.id,
    })
    print("token", token)
    await redis.setex(f"token:{user.id}", settings.JWT['access_token_expire_time'], token)
    # 7.删除redis中保存的验证码，防止一码多用
    await redis.delete(f'sms:{user_info.mobile}')
    # 8. 返回结构
    return {
        'id': user.id,
        'nickname': user.nickname,
        'avatar': user.avatar,
        'code': status.HTTP_200_OK,
        'message': '用户注册成功',
        'status': 'Success',
        'token': token
    }

@app.post('/wx/login', response_model= scheams.UserRegisterResponse)
async def login(request: Request, user_info: scheams.UserLoginRequest):
    """用户登录"""
    # 1. 判断验证码是否正确
    redis = request.app.state.redis
    redis_sms = await redis.get(f'sms:{user_info.mobile}')
    if redis_sms is None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="验证码已过期")
    if redis_sms != user_info.sms_code:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="验证码错误")
    # 2. 判断当前用户是否存在
    result = wechat_tools.get_wechat_info(user_info.code)

    user = await models.User.filter(Q(mobile=user_info.mobile) | Q(openid=result['openid'])).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户不存在")
    # 3. 判断密码是否正确
    hashing = tools.Hashing()
    ret = hashing.verify(user_info.password, user.password)
    if not ret:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="账号或密码错误")
    # 4. 生成token并保存到redis中
    token = JwtToken.create_token({
        'id': user.id,
        })
    await redis.setex(f"token:{user.id}", settings.JWT['access_token_expire_time'], token)
    # 5. 记录用户的登录记录
    # await models.UserLoginRecord.create(user_id=user.id, ip=request.client.host)
    # 删除redis中保存的验证码，防止一码多用
    await redis.delete(f'sms:{user_info.mobile}')
    # 7. 返回结构
    return {
        'id': user.id,
        'nickname': user.nickname,
        'avatar': user.avatar,
        'code': status.HTTP_200_OK,
        'message': '用户登录成功',
        'status': 'Success',
        'token': token
    }

@app.post('/login')
async def login(request: Request, user_info: scheams.UserLoginRequest):
    """用户登录"""
    # 1. 判断验证码是否正确